//
// SoapTrace.Net - A soap message monitoring utility. 
//
// Copyright (C) 2004-2009 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using SoapTrace.Core.Diagnostics;
using System;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
using System.Text;

namespace SoapTrace
{
	/// <summary>
	/// Shows the Soap Trace app's debug messages.
	/// </summary>
	public partial class DebugMessagesForm : System.Windows.Forms.Form
	{
		/// <summary>
		/// The debug message monitor that owns this form.
		/// </summary>
		private DebugMessageMonitor m_Monitor;
		
		/// <summary>
		/// Flag that determines whether events are raised.
		/// </summary>
		/// <remarks>Used to stop events from being raised when
		/// the values of controls are being changed programmatically.
		/// </remarks>
		private bool m_RaiseEvents = true;
		
		/// <summary>
		/// Creates a new instance of the <see cref="DebugMessagesForm"/>
		/// </summary>
		public DebugMessagesForm( DebugMessageMonitor monitor )
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent( );
			
			m_Monitor = monitor;
			
			DisableEvents( );
			
			LogLevelComboBox.Items.Add( LogLevel.Debug );
			LogLevelComboBox.Items.Add( LogLevel.Error );
			LogLevelComboBox.Items.Add( LogLevel.Info );
			LogLevelComboBox.Items.Add( LogLevel.Warn );
			
			LogLevelComboBox.SelectedIndex = 0;

			LogBytesAsStringCheckBox.Checked = monitor.LogBytesAsString;
						
			EnableEvents( );
		}
		
		/// <summary>
		/// Adds log entries to the <see cref="DebugMessagesForm"/>
		/// </summary>
		/// <param name="entries"></param>
		public void Add( LogEntryCollection entries )
		{
			StringBuilder Messages = new StringBuilder( );
			
			foreach( LogEntry Entry in entries )
			{
				Messages.Append( GetEntryText( Entry ) );
			}
			
			MessagesTextBox.Text = Messages.ToString( );

			ScrollToEnd( );
		}
		
		/// <summary>
		/// Adds a single <see cref="LogEntry"/> to the list of 
		/// messages on display.
		/// </summary>
		/// <param name="entry">A <see cref="LogEntry"/> to 
		/// add to the display.</param>
		public void Add( LogEntry entry )
		{
			MessagesTextBox.Text += GetEntryText( entry );
			
			ScrollToEnd( );
		}
		
		/// <summary>
		/// Clears the debug messages.
		/// </summary>
		public void Clear( )
		{
			MessagesTextBox.Text = String.Empty;
		}
		
		/// <summary>
		/// Gets or sets the debug message limit.
		/// </summary>
		public int MessageLimit
		{
			get
			{
				return ( int )MessageCountUpDown.Value;
			}
			
			set
			{
				MessageCountUpDown.Value = ( decimal )value;
			}
		}
		
		/// <summary>
		/// Gets or sets the log level.
		/// </summary>
		public LogLevel Level
		{
			get
			{
				return ( LogLevel )LogLevelComboBox.SelectedItem;
			}
			
			set
			{
				LogLevelComboBox.SelectedItem = value;
			}
		}
				
		/// <summary>
		/// The log level has been changed in the combo box.
		/// </summary>
		/// <param name="sender">The event source.</param>
		/// <param name="e">The event arguments.</param>
		private void LogLevelComboBoxSelectedIndexChanged(object sender, EventArgs e)
		{	
			if( m_RaiseEvents )
			{
				if( LogLevelComboBox.SelectedItem != null )
				{
					m_Monitor.Level = ( LogLevel )LogLevelComboBox.SelectedItem;
				}
			}
		}
		
		/// <summary>
		/// Closes the form.
		/// </summary>
		/// <param name="sender">The event source.</param>
		/// <param name="e">The event arguments.</param>
		private void CloseButtonClick(object sender, EventArgs e)
		{
			Close( );
		}
		
		/// <summary>
		/// Clears the displayed debug messages.
		/// </summary>
		/// <param name="sender">The event source.</param>
		/// <param name="e">The event arguments.</param>
		private void ClearButtonClick(object sender, EventArgs e)
		{
			m_Monitor.Clear( );
		}
		
		/// <summary>
		/// Debug message count has been changed.
		/// </summary>
		/// <param name="sender">The event source.</param>
		/// <param name="e">The event arguments.</param>
		private void MessageCountUpDownValueChanged(object sender, EventArgs e)
		{
			m_Monitor.MessageLimit = ( int )MessageCountUpDown.Value;
		}
		
		/// <summary>
		/// Makes sure the last line of text is visible.
		/// </summary>
		private void ScrollToEnd( )
		{
			MessagesTextBox.SelectionLength = 0;
			MessagesTextBox.SelectionStart = MessagesTextBox.Text.Length;
			MessagesTextBox.ScrollToCaret( );			
		}
		
		/// <summary>
		/// Gets the text that will be displayed for one 
		/// log entry.
		/// </summary>
		/// <param name="entry">A <see cref="LogEntry"/>.</param>
		/// <returns>A formatted log entry string.</returns>
		private static string GetEntryText( LogEntry entry )
		{
			return String.Concat( entry.CreationDate.ToString( CultureInfo.InvariantCulture ), " ", entry.Message, "\r\n" );
		}
		
		/// <summary>
		/// Disables the raising of events.
		/// </summary>
		private void DisableEvents( )
		{
			m_RaiseEvents = false;
		}
		
		/// <summary>
		/// Enables the raising of events.
		/// </summary>
		private void EnableEvents( )
		{
			m_RaiseEvents = true;
		}

		/// <summary>
		/// Saves the state of the log bytes as string check box.
		/// </summary>
		private void LogBytesAsStringCheckBoxCheckedChanged( object sender, EventArgs e )
		{
			if( m_RaiseEvents )
			{
				m_Monitor.LogBytesAsString = LogBytesAsStringCheckBox.Checked;
			}			
		}		
	}
}
